#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <ctype.h>
#include <error.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include "utils.h"
void * xmalloc(size_t size)
{
    void *result = malloc(size);
    if (result == NULL)
    {
        error(1, errno, "xmalloc");
        return NULL;
    }
    else
        return result;
}

void * xcalloc(size_t size)
{
    void *result = calloc(1, size);
    if (result == NULL)
    {
        error(1, errno, "xcalloc");
        return NULL;
    }
    else
        return result;
}

void * xrealloc(void *base, size_t size)
{
    void *result = realloc(base, size);
    if (result == NULL)
    {
        error(1, errno, "xrealloc");
        return NULL;
    }
    else
        return result;
}

extern char ** current_script_argv;
extern int current_script_argc;

char * get_env_variable(const char *str)
{

    if (str == NULL)
        return NULL;
    if (str[0] == '#')
    {
        vchar res = vchar_itoa(current_script_argc);
        return res.str;
    }

    if (str[0] == '*')
    {
        vchar bf;
        vchar_init(&bf);
        vchar_append_str(&bf, current_script_argv[0]);
        for (int i = 1; i < current_script_argc; i++)
        {
            vchar_append(&bf, ' ');
            vchar_append_str(&bf, current_script_argv[i]);
        }
        return bf.str;
    }

    if (isdigit(str[0]) && ((str[0] - '0') < current_script_argc))
        return strdup(current_script_argv[str[0] - '0']);
    else
    {
        char *name = getenv(str);
        if (name != NULL)
            return strdup(name);
        else
            return NULL;
    }
}

char * extract_var_name(char *str)
{
    vchar buff;
    vchar_init(&buff);
    size_t i = 0;
    if (str[0] == '#' || str[0] == '*' || isdigit(str[0]))
        vchar_append(&buff, str[0]);
    else
        if (isalpha(str[0]))
            while (isalnum(str[i]) || str[i] == '_')
            {
                vchar_append(&buff, str[i]);
                i++;
            }
    vchar_append(&buff, 0);
    return buff.str;
}


#define BUFFER_LEN 1024
void update_env_dir()
{
    char *buffer = (char *) xmalloc(sizeof(char) * BUFFER_LEN);
    getcwd(buffer, BUFFER_LEN);
    setenv(PWD_VARIABLE_NAME, buffer, 1);
    free(buffer);
}

void print_help()
{
    printf("Usage Shell [scriptname] [args]\n");
    printf("Shell --help for help\n");
}

